home *** CD-ROM | disk | FTP | other *** search
/ PC World 2007 December / PCWorld_2007-12_cd.bin / v cisle / htttrack / httrack-3.41-3.exe / {app} / src / httrack.c < prev    next >
C/C++ Source or Header  |  2006-08-15  |  27KB  |  780 lines

  1. /* ------------------------------------------------------------ */
  2. /*
  3. HTTrack Website Copier, Offline Browser for Windows and Unix
  4. Copyright (C) Xavier Roche and other contributors
  5.  
  6. This program is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU General Public License
  8. as published by the Free Software Foundation; either version 2
  9. of the License, or any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  19.  
  20.  
  21. Important notes:
  22.  
  23. - We hereby ask people using this source NOT to use it in purpose of grabbing
  24. emails addresses, or collecting any other private information on persons.
  25. This would disgrace our work, and spoil the many hours we spent on it.
  26.  
  27.  
  28. Please visit our Website: http://www.httrack.com
  29. */
  30.  
  31.  
  32. /* ------------------------------------------------------------ */
  33. /* File: htsshow.c console progress info                        */
  34. /* Only used on Linux version                                   */
  35. /* Author: Xavier Roche                                         */
  36. /* ------------------------------------------------------------ */
  37.  
  38. #ifndef _WIN32
  39. #ifndef Sleep
  40. #define Sleep(a) { if (((a)*1000)%1000000) usleep(((a)*1000)%1000000); if (((a)*1000)/1000000) sleep(((a)*1000)/1000000); }
  41. #endif
  42. #endif
  43.  
  44. #include "httrack-library.h"
  45.  
  46. #include "htsglobal.h"
  47. #include "htsbase.h"
  48. #include "htsopt.h"
  49. #include "htsdefines.h"
  50. #include "httrack.h"
  51. #include "htslib.h"
  52.  
  53. /* Static definitions */
  54. static int fexist(const char* s);
  55. static int linput(FILE* fp,char* s,int max);
  56.  
  57.  
  58. // htswrap_add
  59. #include "htswrap.h"
  60.  
  61. /* specific definitions */
  62. //#include "htsbase.h"
  63. #include <stdio.h>
  64. #include <stdlib.h>
  65. #include <string.h>
  66. #include <signal.h>
  67. #ifdef HAVE_SYS_TYPES_H
  68. #include <sys/types.h>
  69. #endif
  70. #ifdef HAVE_SYS_STAT_H
  71. #include <sys/stat.h>
  72. #endif
  73. #ifdef HAVE_UNISTD_H
  74. #include <unistd.h>
  75. #endif
  76. #include <ctype.h>
  77. /* END specific definitions */
  78.  
  79. static void  __cdecl htsshow_init(t_hts_callbackarg *carg);
  80. static void  __cdecl htsshow_uninit(t_hts_callbackarg *carg);
  81. static int   __cdecl htsshow_start(t_hts_callbackarg *carg, httrackp* opt);
  82. static int   __cdecl htsshow_chopt(t_hts_callbackarg *carg, httrackp* opt);
  83. static int   __cdecl htsshow_end(t_hts_callbackarg *carg, httrackp* opt);
  84. static int   __cdecl htsshow_preprocesshtml(t_hts_callbackarg *carg, httrackp *opt, char** html,int* len,const char* url_address,const char* url_file);
  85. static int   __cdecl htsshow_postprocesshtml(t_hts_callbackarg *carg, httrackp *opt, char** html,int* len,const char* url_address,const char* url_file);
  86. static int   __cdecl htsshow_checkhtml(t_hts_callbackarg *carg, httrackp *opt, char* html,int len,const char* url_address,const char* url_file);
  87. static int   __cdecl htsshow_loop(t_hts_callbackarg *carg, httrackp *opt, lien_back* back,int back_max,int back_index,int lien_n,int lien_tot,int stat_time,hts_stat_struct* stats);
  88. static const char* __cdecl htsshow_query(t_hts_callbackarg *carg, httrackp *opt, const char* question);
  89. static const char* __cdecl htsshow_query2(t_hts_callbackarg *carg, httrackp *opt, const char* question);
  90. static const char* __cdecl htsshow_query3(t_hts_callbackarg *carg, httrackp *opt, const char* question);
  91. static int   __cdecl htsshow_check(t_hts_callbackarg *carg, httrackp *opt, const char* adr,const char* fil,int status);
  92. static int   __cdecl htsshow_check_mime(t_hts_callbackarg *carg, httrackp *opt, const char* adr,const char* fil,const char* mime,int status);
  93. static void  __cdecl htsshow_pause(t_hts_callbackarg *carg, httrackp *opt, const char* lockfile);
  94. static void  __cdecl htsshow_filesave(t_hts_callbackarg *carg, httrackp *opt, const char* file);
  95. static void  __cdecl htsshow_filesave2(t_hts_callbackarg *carg, httrackp *opt, const char* adr, const char* fil, const char* save, int is_new, int is_modified,int not_updated);
  96. static int   __cdecl htsshow_linkdetected(t_hts_callbackarg *carg, httrackp *opt, char* link);
  97. static int   __cdecl htsshow_linkdetected2(t_hts_callbackarg *carg, httrackp *opt, char* link, const char* start_tag);
  98. static int   __cdecl htsshow_xfrstatus(t_hts_callbackarg *carg, httrackp *opt, lien_back* back);
  99. static int   __cdecl htsshow_savename(t_hts_callbackarg *carg, httrackp *opt, const char* adr_complete,const char* fil_complete,const char* referer_adr,const char* referer_fil,char* save);
  100. static int   __cdecl htsshow_sendheader(t_hts_callbackarg *carg, httrackp *opt, char* buff, const char* adr, const char* fil, const char* referer_adr, const char* referer_fil, htsblk* outgoing);
  101. static int   __cdecl htsshow_receiveheader(t_hts_callbackarg *carg, httrackp *opt, char* buff, const char* adr, const char* fil, const char* referer_adr, const char* referer_fil, htsblk* incoming);
  102.  
  103. static void vt_color(int text,int back);
  104. static void vt_clear(void);
  105. static void vt_home(void);
  106.  
  107. // ISO VT100/220 definitions
  108. #define VT_COL_TEXT_BLACK    "30"
  109. #define VT_COL_TEXT_RED      "31"
  110. #define VT_COL_TEXT_GREEN    "32"
  111. #define VT_COL_TEXT_YELLOW   "33"
  112. #define VT_COL_TEXT_BLUE     "34"
  113. #define VT_COL_TEXT_MAGENTA  "35"
  114. #define VT_COL_TEXT_CYAN     "36"
  115. #define VT_COL_TEXT_WHITE    "37"
  116. #define VT_COL_BACK_BLACK    "40"
  117. #define VT_COL_BACK_RED      "41"
  118. #define VT_COL_BACK_GREEN    "42"
  119. #define VT_COL_BACK_YELLOW   "43"
  120. #define VT_COL_BACK_BLUE     "44"
  121. #define VT_COL_BACK_MAGENTA  "45"
  122. #define VT_COL_BACK_CYAN     "46"
  123. #define VT_COL_BACK_WHITE    "47"
  124. //
  125. #define VT_GOTOXY(X,Y)  "\33["Y";"X"f"
  126. #define VT_COLOR(C)     "\33["C"m"
  127. #define VT_RESET        "\33[m"
  128. #define VT_REVERSE      "\33[7m"
  129. #define VT_UNREVERSE    "\33[27m"
  130. #define VT_BOLD         "\33[1m"
  131. #define VT_UNBOLD       "\33[22m"
  132. #define VT_BLINK        "\33[5m"
  133. #define VT_UNBLINK      "\33[25m"
  134. //
  135. #define VT_CLREOL       "\33[K"
  136. #define VT_CLRSOL       "\33[1K"
  137. #define VT_CLRLIN       "\33[2K"
  138. #define VT_CLREOS       "\33[J"
  139. #define VT_CLRSOS       "\33[1J"
  140. #define VT_CLRSCR       "\33[2J"
  141. //
  142. #define csi(X)          printf(s_csi( X ));
  143. static void vt_clear(void) {
  144.   printf("%s%s%s",VT_RESET,VT_CLRSCR,VT_GOTOXY("1","0"));
  145. }
  146. static void vt_home(void) {
  147.   printf("%s%s",VT_RESET,VT_GOTOXY("1","0"));
  148. }
  149. //
  150.  
  151.  
  152. /*
  153. #define STYLE_STATVALUES VT_COLOR(VT_COL_TEXT_BLACK)
  154. #define STYLE_STATTEXT   VT_COLOR(VT_COL_TEXT_BLUE)   
  155. */
  156. #define STYLE_STATVALUES VT_BOLD
  157. #define STYLE_STATTEXT   VT_UNBOLD
  158. #define STYLE_STATRESET  VT_UNBOLD
  159. #define NStatsBuffer     14
  160. #define MAX_LEN_INPROGRESS 40
  161.  
  162. static int use_show;
  163. static httrackp *global_opt = NULL;
  164.  
  165. static void signal_handlers(void);
  166.  
  167. int main(int argc, char **argv) {
  168.   int ret = 0;
  169.   httrackp *opt;
  170.  
  171. #ifdef _WIN32
  172.   {
  173.     WORD   wVersionRequested;   // requested version WinSock API
  174.     WSADATA wsadata;            // Windows Sockets API data
  175.     int stat;
  176.     wVersionRequested = 0x0101;
  177.     stat = WSAStartup( wVersionRequested, &wsadata );
  178.     if (stat != 0) {
  179.       printf("Winsock not found!\n");
  180.       return;
  181.     } else if (LOBYTE(wsadata.wVersion) != 1  && HIBYTE(wsadata.wVersion) != 1) {
  182.       printf("WINSOCK.DLL does not support version 1.1\n");
  183.       WSACleanup();
  184.       return;
  185.     }
  186.   }
  187. #endif
  188.  
  189.     signal_handlers();
  190.   hts_init();
  191.   opt = global_opt = hts_create_opt();
  192.  
  193.   CHAIN_FUNCTION(opt, init, htsshow_init, NULL);
  194.   CHAIN_FUNCTION(opt, uninit, htsshow_uninit, NULL);
  195.   CHAIN_FUNCTION(opt, start, htsshow_start, NULL);
  196.   CHAIN_FUNCTION(opt, end, htsshow_end, NULL);
  197.   CHAIN_FUNCTION(opt, chopt, htsshow_chopt, NULL);
  198.   CHAIN_FUNCTION(opt, preprocess, htsshow_preprocesshtml, NULL);
  199.   CHAIN_FUNCTION(opt, postprocess, htsshow_postprocesshtml, NULL);
  200.   CHAIN_FUNCTION(opt, check_html, htsshow_checkhtml, NULL);
  201.   CHAIN_FUNCTION(opt, query, htsshow_query, NULL);
  202.   CHAIN_FUNCTION(opt, query2, htsshow_query2, NULL);
  203.   CHAIN_FUNCTION(opt, query3, htsshow_query3, NULL);
  204.   CHAIN_FUNCTION(opt, loop, htsshow_loop, NULL);
  205.   CHAIN_FUNCTION(opt, check_link, htsshow_check, NULL);
  206.   CHAIN_FUNCTION(opt, check_mime, htsshow_check_mime, NULL);
  207.   CHAIN_FUNCTION(opt, pause, htsshow_pause, NULL);
  208.   CHAIN_FUNCTION(opt, filesave, htsshow_filesave, NULL);
  209.   CHAIN_FUNCTION(opt, filesave2, htsshow_filesave2, NULL);
  210.   CHAIN_FUNCTION(opt, linkdetected, htsshow_linkdetected, NULL);
  211.   CHAIN_FUNCTION(opt, linkdetected2, htsshow_linkdetected2, NULL);
  212.   CHAIN_FUNCTION(opt, xfrstatus, htsshow_xfrstatus, NULL);
  213.   CHAIN_FUNCTION(opt, savename, htsshow_savename, NULL);
  214.   CHAIN_FUNCTION(opt, sendhead, htsshow_sendheader, NULL);
  215.   CHAIN_FUNCTION(opt, receivehead, htsshow_receiveheader, NULL);
  216.  
  217.     ret = hts_main2(argc, argv, opt);
  218.   if (ret) {
  219.     fprintf(stderr, "* %s\n", hts_errmsg(opt));
  220.   }
  221.     global_opt = NULL;
  222.     hts_free_opt(opt);
  223.   htsthread_wait();   /* wait for pending threads */
  224.     hts_uninit();
  225.  
  226. #ifdef _WIN32
  227.   WSACleanup();
  228. #endif
  229.  
  230.     return ret;
  231. }
  232.  
  233.  
  234. /* CALLBACK FUNCTIONS */
  235.  
  236. /* Initialize the Winsock */
  237. static void __cdecl htsshow_init(t_hts_callbackarg *carg) {
  238. }
  239. static void __cdecl htsshow_uninit(t_hts_callbackarg *carg) {
  240. }
  241. static int __cdecl htsshow_start(t_hts_callbackarg *carg, httrackp* opt) {
  242.   use_show=0;
  243.   if (opt->verbosedisplay==2) {
  244.     use_show=1;
  245.     vt_clear();
  246.   }
  247.   return 1; 
  248. }
  249. static int __cdecl htsshow_chopt(t_hts_callbackarg *carg, httrackp* opt) {
  250.   return htsshow_start(carg, opt);
  251. }
  252. static int  __cdecl htsshow_end(t_hts_callbackarg *carg, httrackp* opt) { 
  253.   return 1; 
  254. }
  255. static int __cdecl htsshow_preprocesshtml(t_hts_callbackarg *carg, httrackp *opt, char** html,int* len,const char* url_address,const char* url_file) {
  256.   return 1;
  257. }
  258. static int __cdecl htsshow_postprocesshtml(t_hts_callbackarg *carg, httrackp *opt, char** html,int* len,const char* url_address,const char* url_file) {
  259.   return 1;
  260. }
  261. static int __cdecl htsshow_checkhtml(t_hts_callbackarg *carg, httrackp *opt, char* html,int len,const char* url_address,const char* url_file) {
  262.   return 1;
  263. }
  264. static int __cdecl htsshow_loop(t_hts_callbackarg *carg, httrackp *opt, lien_back* back,int back_max,int back_index,int lien_n,int lien_tot,int stat_time, hts_stat_struct* stats) {    // appelΘ α chaque boucle de HTTrack
  265.   static TStamp prev_mytime=0; /* ok */
  266.   static t_InpInfo SInfo; /* ok */
  267.   //
  268.   TStamp mytime;
  269.   long int rate=0;
  270.   char st[256];
  271.   //
  272.   int stat_written=-1;
  273.   int stat_updated=-1;
  274.   int stat_errors=-1;
  275.   int stat_warnings=-1;
  276.   int stat_infos=-1;
  277.   int nbk=-1;
  278.   LLint nb=-1;
  279.   int stat_nsocket=-1;
  280.   LLint stat_bytes=-1;
  281.   LLint stat_bytes_recv=-1;
  282.   int irate=-1;
  283.   if (stats) {
  284.     stat_written=stats->stat_files;
  285.     stat_updated=stats->stat_updated_files;
  286.     stat_errors=stats->stat_errors;
  287.     stat_warnings=stats->stat_warnings;
  288.     stat_infos=stats->stat_infos;
  289.     nbk=stats->nbk;
  290.     stat_nsocket=stats->stat_nsocket;
  291.     irate=(int)stats->rate;
  292.     nb=stats->nb;
  293.     stat_bytes=stats->nb;
  294.     stat_bytes_recv=stats->HTS_TOTAL_RECV;
  295.   }
  296.  
  297.   if (!use_show)
  298.     return 1;
  299.  
  300.   mytime=mtime_local();
  301.   if ((stat_time>0) && (stat_bytes_recv>0))
  302.     rate=(int)(stat_bytes_recv/stat_time);
  303.   else
  304.     rate=0;    // pas d'infos
  305.  
  306.   /* Infos */
  307.   if (stat_bytes>=0) SInfo.stat_bytes=stat_bytes;      // bytes
  308.   if (stat_time>=0) SInfo.stat_time=stat_time;         // time
  309.   if (lien_tot>=0) SInfo.lien_tot=lien_tot; // nb liens
  310.   if (lien_n>=0) SInfo.lien_n=lien_n;       // scanned
  311.   SInfo.stat_nsocket=stat_nsocket;          // socks
  312.   if (rate>0)  SInfo.rate=rate;                // rate
  313.   if (irate>=0) SInfo.irate=irate;             // irate
  314.   if (SInfo.irate<0) SInfo.irate=SInfo.rate;
  315.   if (nbk>=0) SInfo.stat_back=nbk;
  316.   if (stat_written>=0) SInfo.stat_written=stat_written;
  317.   if (stat_updated>=0) SInfo.stat_updated=stat_updated;
  318.   if (stat_errors>=0)  SInfo.stat_errors=stat_errors;
  319.   if (stat_warnings>=0)  SInfo.stat_warnings=stat_warnings;
  320.   if (stat_infos>=0)  SInfo.stat_infos=stat_infos;
  321.  
  322.  
  323.   if ( ((mytime - prev_mytime)>100) || ((mytime - prev_mytime)<0) ) {
  324.         strc_int2bytes2 strc, strc2, strc3;
  325.     prev_mytime=mytime;
  326.  
  327.     
  328.     st[0]='\0';
  329.     qsec2str(st,stat_time);
  330.     vt_home();
  331.     printf(
  332.     VT_GOTOXY("1","1")
  333.     VT_CLREOL
  334.                            STYLE_STATTEXT   "Bytes saved:"
  335.                            STYLE_STATVALUES " \t%s"
  336.                            "\t"
  337.     VT_CLREOL
  338.     VT_GOTOXY("40","1")
  339.                            STYLE_STATTEXT   "Links scanned:"
  340.                            STYLE_STATVALUES " \t%d/%d (+%d)"
  341.     VT_CLREOL"\n"VT_CLREOL
  342.     VT_GOTOXY("1","2")
  343.                            STYLE_STATTEXT   "Time:"
  344.                                             " \t"
  345.                            STYLE_STATVALUES "%s"
  346.                            "\t"
  347.     VT_CLREOL
  348.     VT_GOTOXY("40","2")
  349.                            STYLE_STATTEXT   "Files written:"
  350.                                             " \t"
  351.                            STYLE_STATVALUES "%d"
  352.     VT_CLREOL"\n"VT_CLREOL
  353.     VT_GOTOXY("1","3")
  354.                            STYLE_STATTEXT   "Transfer rate:"
  355.                                             " \t"
  356.                            STYLE_STATVALUES "%s (%s)"
  357.                            "\t"
  358.     VT_CLREOL
  359.     VT_GOTOXY("40","3")
  360.                            STYLE_STATTEXT   "Files updated:"
  361.                                             " \t"
  362.                            STYLE_STATVALUES "%d"
  363.     VT_CLREOL"\n"VT_CLREOL
  364.     VT_GOTOXY("1","4")
  365.                            STYLE_STATTEXT   "Active connections:"
  366.                                             " \t"
  367.                            STYLE_STATVALUES "%d"
  368.                            "\t"
  369.     VT_CLREOL
  370.     VT_GOTOXY("40","4")
  371.                            STYLE_STATTEXT   "Errors:"
  372.                            STYLE_STATVALUES " \t"
  373.                            STYLE_STATVALUES "%d"
  374.     VT_CLREOL"\n"
  375.     STYLE_STATRESET
  376.     ,
  377.       /* */
  378.       (char*)int2bytes(&strc,SInfo.stat_bytes),
  379.       (int)lien_n,(int)SInfo.lien_tot,(int)nbk,
  380.       (char*)st,
  381.       (int)SInfo.stat_written,
  382.       (char*)int2bytessec(&strc2,SInfo.irate),(char*)int2bytessec(&strc3,SInfo.rate),
  383.       (int)SInfo.stat_updated,
  384.       (int)SInfo.stat_nsocket,
  385.       (int)SInfo.stat_errors
  386.       /* */
  387.       );
  388.  
  389.     
  390.     // parcourir registre des liens
  391.     if (back_index>=0) {  // seulement si index passΘ
  392.       int j,k;
  393.       int index=0;
  394.       int ok=0;         // idem
  395.       int l;            // idem
  396.       //
  397.       t_StatsBuffer StatsBuffer[NStatsBuffer];
  398.       
  399.       {
  400.         int i;
  401.         for(i=0;i<NStatsBuffer;i++) {
  402.           strcpybuff(StatsBuffer[i].state,"");
  403.           strcpybuff(StatsBuffer[i].name,"");
  404.           strcpybuff(StatsBuffer[i].file,"");
  405.           strcpybuff(StatsBuffer[i].url_sav,"");
  406.           StatsBuffer[i].back=0;
  407.           StatsBuffer[i].size=0;
  408.           StatsBuffer[i].sizetot=0;
  409.         }
  410.       }
  411.       for(k=0;k<2;k++) {    // 0: lien en cours 1: autres liens
  412.         for(j=0;(j<3) && (index<NStatsBuffer);j++) {  // passe de prioritΘ
  413.           int _i;
  414.           for(_i=0+k;(_i< max(back_max*k,1) ) && (index<NStatsBuffer);_i++) {  // no lien
  415.             int i=(back_index+_i)%back_max;    // commencer par le "premier" (l'actuel)
  416.             if (back[i].status>=0) {     // signifie "lien actif"
  417.               // int ok=0;  // OPTI
  418.               ok=0;
  419.               switch(j) {
  420.               case 0:     // prioritaire
  421.                 if ((back[i].status>0) && (back[i].status<99)) {
  422.                   strcpybuff(StatsBuffer[index].state,"receive"); ok=1;
  423.                 }
  424.                 break;
  425.               case 1:
  426.                 if (back[i].status==STATUS_WAIT_HEADERS) {
  427.                   strcpybuff(StatsBuffer[index].state,"request"); ok=1;
  428.                 }
  429.                 else if (back[i].status==STATUS_CONNECTING) {
  430.                   strcpybuff(StatsBuffer[index].state,"connect"); ok=1;
  431.                 }
  432.                 else if (back[i].status==STATUS_WAIT_DNS) {
  433.                   strcpybuff(StatsBuffer[index].state,"search"); ok=1;
  434.                 }
  435.                 else if (back[i].status==STATUS_FTP_TRANSFER) {    // ohh le beau ftp
  436.                   sprintf(StatsBuffer[index].state,"ftp: %s",back[i].info); ok=1;
  437.                 }
  438.                 break;
  439.               default:
  440.                 if (back[i].status==STATUS_READY) {  // prΩt
  441.                   if ((back[i].r.statuscode==200)) {
  442.                     strcpybuff(StatsBuffer[index].state,"ready"); ok=1;
  443.                   }
  444.                   else if ((back[i].r.statuscode>=100) && (back[i].r.statuscode<=599)) {
  445.                     char tempo[256]; tempo[0]='\0';
  446.                     infostatuscode(tempo,back[i].r.statuscode);
  447.                     strcpybuff(StatsBuffer[index].state,tempo); ok=1;
  448.                   }
  449.                   else {
  450.                     strcpybuff(StatsBuffer[index].state,"error"); ok=1;
  451.                   }
  452.                 }
  453.                 break;
  454.               }
  455.               
  456.               if (ok) {
  457.                 char BIGSTK s[HTS_URLMAXSIZE*2];
  458.                 //
  459.                 StatsBuffer[index].back=i;        // index pour + d'infos
  460.                 //
  461.                 s[0]='\0';
  462.                 strcpybuff(StatsBuffer[index].url_sav,back[i].url_sav);   // pour cancel
  463.                 if (strcmp(back[i].url_adr,"file://"))
  464.                   strcatbuff(s,back[i].url_adr);
  465.                 else
  466.                   strcatbuff(s,"localhost");
  467.                 if (back[i].url_fil[0]!='/')
  468.                   strcatbuff(s,"/");
  469.                 strcatbuff(s,back[i].url_fil);
  470.                 
  471.                 StatsBuffer[index].file[0]='\0';
  472.                 {
  473.                   char* a=strrchr(s,'/');
  474.                   if (a) {
  475.                     strncatbuff(StatsBuffer[index].file,a,200);
  476.                     *a='\0';
  477.                   }
  478.                 }
  479.                 
  480.                 if ((l = (int) strlen(s))<MAX_LEN_INPROGRESS)
  481.                   strcpybuff(StatsBuffer[index].name,s);
  482.                 else {
  483.                   // couper
  484.                   StatsBuffer[index].name[0]='\0';
  485.                   strncatbuff(StatsBuffer[index].name,s,MAX_LEN_INPROGRESS/2-2);
  486.                   strcatbuff(StatsBuffer[index].name,"...");
  487.                   strcatbuff(StatsBuffer[index].name,s+l-MAX_LEN_INPROGRESS/2+2);
  488.                 }
  489.                                
  490.                 if (back[i].r.totalsize>0) {  // taille prΘdΘfinie
  491.                   StatsBuffer[index].sizetot=back[i].r.totalsize;
  492.                   StatsBuffer[index].size=back[i].r.size;
  493.                 } else {  // pas de taille prΘdΘfinie
  494.                   if (back[i].status==STATUS_READY) {  // prΩt
  495.                     StatsBuffer[index].sizetot=back[i].r.size;
  496.                     StatsBuffer[index].size=back[i].r.size;
  497.                   } else {
  498.                     StatsBuffer[index].sizetot=8192;
  499.                     StatsBuffer[index].size=(back[i].r.size % 8192);
  500.                   }
  501.                 }
  502.                 index++;
  503.               }
  504.             }
  505.           }
  506.         }
  507.       }
  508.  
  509.       /* LF */
  510.       printf("%s\n",VT_CLREOL);
  511.  
  512.       /* Display current job */
  513.       {
  514.         int parsing=0;
  515.         printf("Current job: ");
  516.         if (!(parsing=hts_is_parsing(opt, -1)))
  517.           printf("receiving files");
  518.         else {
  519.           switch(hts_is_testing(opt)) {
  520.           case 0:
  521.             printf("parsing HTML file (%d%%)",parsing);
  522.             break;
  523.           case 1:
  524.             printf("parsing HTML file: testing links (%d%%)",parsing);
  525.             break;
  526.           case 2:
  527.             printf("purging files");
  528.             break;
  529.           case 3:
  530.             printf("loading cache");
  531.             break;
  532.           case 4:
  533.             printf("waiting (scheduler)");
  534.             break;
  535.           case 5:
  536.             printf("waiting (throttle)");
  537.             break;
  538.           }
  539.         }
  540.         printf("%s\n",VT_CLREOL);
  541.       }
  542.       
  543.       /* Display background jobs */
  544.       {
  545.         int i;
  546.         for(i=0;i<NStatsBuffer;i++) {
  547.           if (strnotempty(StatsBuffer[i].state)) {
  548.             printf(VT_CLREOL" %s - \t%s%s \t%s / \t%s",
  549.               StatsBuffer[i].state,
  550.               StatsBuffer[i].name,
  551.               StatsBuffer[i].file,
  552.               int2bytes(&strc,StatsBuffer[i].size),
  553.               int2bytes(&strc2,StatsBuffer[i].sizetot)
  554.               );
  555.           }
  556.           printf("%s\n",VT_CLREOL);
  557.         }
  558.       }
  559.  
  560.  
  561.     }
  562.  
  563.   }
  564.  
  565.  
  566.  
  567.   return 1;
  568. }
  569. static const char* __cdecl htsshow_query(t_hts_callbackarg *carg, httrackp *opt, const char* question) {
  570.   static char s[12]=""; /* ok */
  571.   printf("%s\nPress <Y><Enter> to confirm, <N><Enter> to abort\n",question);
  572.   io_flush; linput(stdin,s,4);
  573.   return s;
  574. }
  575. static const char* __cdecl htsshow_query2(t_hts_callbackarg *carg, httrackp *opt, const char* question) {
  576.   static char s[12]=""; /* ok */
  577.   printf("%s\nPress <Y><Enter> to confirm, <N><Enter> to abort\n",question);
  578.   io_flush; linput(stdin,s,4);
  579.   return s;
  580. }
  581. static const char* __cdecl htsshow_query3(t_hts_callbackarg *carg, httrackp *opt, const char* question) {
  582.   static char line[256]; /* ok */
  583.   do {
  584.     io_flush; linput(stdin,line,206);
  585.   } while(!strnotempty(line));
  586.   printf("ok..\n");
  587.   return line;
  588. }
  589. static int __cdecl htsshow_check(t_hts_callbackarg *carg, httrackp *opt, const char* adr,const char* fil,int status) {
  590.   return -1;
  591. }
  592. static int __cdecl htsshow_check_mime(t_hts_callbackarg *carg, httrackp *opt, const char* adr,const char* fil,const char* mime,int status) {
  593.   return -1;
  594. }
  595. static void __cdecl htsshow_pause(t_hts_callbackarg *carg, httrackp *opt, const char* lockfile) {
  596.   while (fexist(lockfile)) {
  597.     Sleep(1000);
  598.   }
  599. }
  600. static void __cdecl htsshow_filesave(t_hts_callbackarg *carg, httrackp *opt, const char* file) {
  601. }
  602. static void __cdecl htsshow_filesave2(t_hts_callbackarg *carg, httrackp *opt, const char* adr, const char* fil, const char* save, int is_new, int is_modified,int not_updated) {
  603. }
  604. static int __cdecl htsshow_linkdetected(t_hts_callbackarg *carg, httrackp *opt, char* link) {
  605.   return 1;
  606. }
  607. static int __cdecl htsshow_linkdetected2(t_hts_callbackarg *carg, httrackp *opt, char* link, const char* start_tag) {
  608.   return 1;
  609. }
  610. static int __cdecl htsshow_xfrstatus(t_hts_callbackarg *carg, httrackp *opt, lien_back* back) {
  611.   return 1;
  612. }
  613. static int __cdecl htsshow_savename(t_hts_callbackarg *carg, httrackp *opt, const char* adr_complete,const char* fil_complete,const char* referer_adr,const char* referer_fil,char* save) {
  614.   return 1;
  615. }
  616. static int __cdecl htsshow_sendheader(t_hts_callbackarg *carg, httrackp *opt, char* buff, const char* adr, const char* fil, const char* referer_adr, const char* referer_fil, htsblk* outgoing) {
  617.   return 1;
  618. }
  619. static int __cdecl htsshow_receiveheader(t_hts_callbackarg *carg, httrackp *opt, char* buff, const char* adr, const char* fil, const char* referer_adr, const char* referer_fil, htsblk* incoming) {
  620.   return 1;
  621. }
  622.  
  623. /* *** Various functions *** */
  624.  
  625.  
  626. static int fexist(const char* s) {
  627.   struct stat st;
  628.   memset(&st, 0, sizeof(st));
  629.   if (stat(s, &st) == 0) {
  630.     if (S_ISREG(st.st_mode)) {
  631.       return 1;
  632.     }
  633.   }
  634.   return 0;
  635.  
  636. static int linput(FILE* fp,char* s,int max) {
  637.   int c;
  638.   int j=0;
  639.   do {
  640.     c=fgetc(fp);
  641.     if (c!=EOF) {
  642.       switch(c) {
  643.         case 13: break;  // sauter CR
  644.         case 10: c=-1; break;
  645.         case 9: case 12: break;  // sauter ces caractΦres
  646.         default: s[j++]=(char) c; break;
  647.       }
  648.     }
  649.   }  while((c!=-1) && (c!=EOF) && (j<(max-1)));
  650.   s[j]='\0';
  651.   return j;
  652. }
  653.  
  654.  
  655. // routines de dΘtournement de SIGHUP & co (Unix)
  656. //
  657. static void sig_ignore( int code ) {     // ignorer signal
  658. }
  659. static void sig_term( int code ) {       // quitter brutalement
  660.   fprintf(stderr,"\nProgram terminated (signal %d)\n",code);
  661.   exit(0);
  662. }
  663. static void sig_finish( int code ) {       // finir et quitter
  664.   signal(code,sig_term);  // quitter si encore
  665.     if (global_opt != NULL) {
  666.         global_opt->state.exit_xh=1;
  667.     }
  668.   fprintf(stderr,"\nExit requested to engine (signal %d)\n",code);
  669. }
  670. #ifdef _WIN32
  671. static void sig_ask( int code ) {        // demander
  672.   char s[256];
  673.   signal(code,sig_term);  // quitter si encore
  674.   printf("\nQuit program/Interrupt/Cancel? (Q/I/C) ");
  675.   fflush(stdout);
  676.   scanf("%s",s);
  677.   if ( (s[0]=='y') || (s[0]=='Y') || (s[0]=='o') || (s[0]=='O') || (s[0]=='q') || (s[0]=='Q'))
  678.     exit(0);     // quitter
  679.   else if ( (s[0]=='i') || (s[0]=='I') ) {
  680.     if (global_opt != NULL) {
  681.       // ask for stop
  682.       global_opt->state.stop=1;
  683.     }
  684.   }
  685.   signal(code,sig_ask);  // remettre signal
  686. }
  687. #else
  688. static void sig_doback(int blind);
  689. static void sig_back( int code ) {       // ignorer et mettre en backing 
  690.   signal(code,sig_ignore);
  691.   sig_doback(0);
  692. }
  693. static void sig_ask( int code ) {        // demander
  694.   char s[256];
  695.   signal(code,sig_term);  // quitter si encore
  696.   printf("\nQuit program/Interrupt/Background/bLind background/Cancel? (Q/I/B/L/C) ");
  697.   fflush(stdout);
  698.   scanf("%s",s);
  699.   if ( (s[0]=='y') || (s[0]=='Y') || (s[0]=='o') || (s[0]=='O') || (s[0]=='q') || (s[0]=='Q'))
  700.     exit(0);     // quitter
  701.   else if ( (s[0]=='b') || (s[0]=='B') || (s[0]=='a') || (s[0]=='A') )
  702.     sig_doback(0);  // arriΦre plan
  703.   else if ( (s[0]=='l') || (s[0]=='L') )
  704.     sig_doback(1);  // arriΦre plan
  705.   else if ( (s[0]=='i') || (s[0]=='I') ) {
  706.     if (global_opt != NULL) {
  707.       // ask for stop
  708.       printf("finishing pending transfers.. please wait\n");
  709.       global_opt->state.stop=1;
  710.     }
  711.     signal(code,sig_ask);  // remettre signal
  712.   }
  713.   else {
  714.     printf("cancel..\n");
  715.     signal(code,sig_ask);  // remettre signal
  716.   }
  717. }
  718. static void sig_brpipe( int code ) {     // treat if necessary
  719.   signal(code, sig_brpipe);
  720. }
  721. static void sig_doback(int blind) {       // mettre en backing 
  722.   int out=-1;
  723.   //
  724.   printf("\nMoving into background to complete the mirror...\n"); fflush(stdout);
  725.  
  726.     if (global_opt != NULL) {
  727.         // suppress logging and asking lousy questions
  728.         global_opt->quiet=1;
  729.         global_opt->verbosedisplay=0;
  730.   }
  731.  
  732.   if (!blind)
  733.     out = open("hts-nohup.out",O_CREAT|O_WRONLY,S_IRUSR|S_IWUSR);
  734.   if (out == -1)
  735.     out = open("/dev/null",O_WRONLY,S_IRUSR|S_IWUSR);
  736.   close(0);
  737.   close(1);
  738.   dup(out);
  739.   close(2);
  740.   dup(out);
  741.   //
  742.   switch (fork()) {
  743.   case 0: 
  744.     break;
  745.   case -1:
  746.     fprintf(stderr,"Error: can not fork process\n");
  747.     break;
  748.   default:            // pere
  749.     usleep(100000);   // pause 1/10s "A  microsecond  is  .000001s"
  750.     _exit(0);
  751.     break;  
  752.     }
  753. }
  754. #endif
  755.  
  756. static void signal_handlers(void) {
  757. #ifdef _WIN32
  758. #ifndef  _WIN32_WCE
  759. #if 0    /* BUG366763 */
  760.     signal( SIGINT  , sig_ask    );   // ^C
  761. #endif
  762.     signal( SIGTERM , sig_finish );   // kill <process>
  763. #endif
  764. #else
  765. #if 0    /* BUG366763 */
  766.     signal( SIGHUP  , sig_back   );   // close window
  767. #endif
  768.     signal( SIGTSTP , sig_back   );   // ^Z
  769.     signal( SIGTERM , sig_finish );   // kill <process>
  770. #if 0    /* BUG366763 */
  771.     signal( SIGINT  , sig_ask    );   // ^C
  772. #endif
  773.     signal( SIGPIPE , sig_brpipe );   // broken pipe (write into non-opened socket)
  774.     signal( SIGCHLD , sig_ignore );   // child change status
  775. #endif
  776. }
  777.  
  778. // fin routines de dΘtournement de SIGHUP & co
  779.